package com.easyadmin.pro.common.aspect.lock;

import com.easyadmin.pro.common.annotation.lock.RequestLock;
import com.easyadmin.pro.common.enums.HttpCodeEnum;
import com.easyadmin.pro.common.exception.BusinessException;
import com.easyadmin.pro.common.generator.RequestKeyGenerator;
import com.easyadmin.pro.tool.RedisUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * packageName com.easyadmin.pro.common.aspect.lock
 *
 * @author 骑着蚂蚁去上天
 * @version JDK 17
 * @className RequestLockAspect
 * @date 2024/9/3
 * @description 防抖切面工具
 */
@Aspect
@Order(2)
@Component
public class RequestLockAspect {

    @Around("execution(public * * (..)) && @annotation(com.easyadmin.pro.common.annotation.lock.RequestLock)")
    public Object interceptor(ProceedingJoinPoint joinPoint) {
        try {
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            Method method = methodSignature.getMethod();
            RequestLock annotation = method.getAnnotation(RequestLock.class);
            if (Objects.nonNull(annotation)) {
                if (!StringUtils.hasLength(annotation.prefix())) {
                    throw new BusinessException(HttpCodeEnum.REPEAT_COMMIT_PREFIX_IS_EMPTY);
                }
                final String lockKey = RequestKeyGenerator.generator(joinPoint);
                if (Objects.nonNull(RedisUtils.getValue(lockKey))) {
                    throw new BusinessException(HttpCodeEnum.OPERATOR_TOO_FAST_ERROR);
                }
                RedisUtils.setValueValidityPeriod(lockKey, lockKey, annotation.expire(), annotation.timeUnit());
            }
            return joinPoint.proceed();
        } catch (Throwable e) {
            throw new BusinessException(HttpCodeEnum.SYSTEM_ERROR);
        }
    }
}